﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AirPlanIPTunnel
{
    public partial class MainForm : Form
    {
        private bool m_bRecvTcp;
        private bool m_bRecvUdp;
        private ushort m_nRecvTcpPort;
        private ushort m_nRecvUdpPort;
        private ushort m_nSendTcpPort;
        private string m_RecvTcpIp = "";
        private string m_SendTcpIp = "";

        public delegate void delegateInsertList(string strClass, string strDirect, string strInfo);


        public delegate void delegateUpdateText(string strInfo);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);


        public MainForm()
        {
            InitializeComponent();
        }

        public void InitPort()
        {
            string filePath = Application.StartupPath + @"\AirPlanTunnel.ini";
            StringBuilder retVal = new StringBuilder();
            string section = "UdpPort";
            string key = "RecvUdpPort";
            GetPrivateProfileString(section, key, "", retVal, 0x40, filePath);
            string s = retVal.ToString();
            this.m_nRecvUdpPort = ushort.Parse(s);
            section = "TcpPort";
            key = "SendTcpPort";
            GetPrivateProfileString(section, key, "", retVal, 0x40, filePath);
            s = retVal.ToString();
            this.m_nSendTcpPort = ushort.Parse(s);
            key = "SendTcpIp";
            GetPrivateProfileString(section, key, "", retVal, 0x40, filePath);
            this.m_SendTcpIp = retVal.ToString();
            key = "RecvTcpPort";
            GetPrivateProfileString(section, key, "", retVal, 0x40, filePath);
            s = retVal.ToString();
            this.m_nRecvTcpPort = ushort.Parse(s);
            key = "RecvTcpIp";
            GetPrivateProfileString(section, key, "", retVal, 0x40, filePath);
            this.m_RecvTcpIp = retVal.ToString();
        }

        private void InsertList(string strClass, string strDirect, string strInfo)
        {
            if (this.listViewInfo.Items.Count > 500)
            {
                this.listViewInfo.Items.Clear();
            }
            int count = this.listViewInfo.Items.Count;
            this.listViewInfo.Items.Insert(0, count.ToString());
            this.listViewInfo.Items[0].SubItems[0].Text = count.ToString();
            this.listViewInfo.Items[0].SubItems.Add(strClass);
            this.listViewInfo.Items[0].SubItems.Add(strDirect);
            this.listViewInfo.Items[0].SubItems.Add(strInfo);
        }

        public void TcpSend(string IpAddr, int nPort, string strPacketSend)
        {
            byte[] bytes = Encoding.Default.GetBytes(strPacketSend);
            TcpClient client = new TcpClient();
            try
            {
                client.Connect(IpAddr, nPort);
                if (client.Connected)
                {
                    NetworkStream stream = client.GetStream();
                    if (stream.CanWrite)
                    {
                        stream.Write(bytes, 0, bytes.Length);
                        stream.Close();
                    }
                }
            }
            catch (Exception exception)
            {
                string message = exception.Message;
            }
            finally
            {
                client.Close();
            }
        }

        private void threadListenTcp()
        {
            try
            {
                TcpListener listener = new TcpListener(this.m_nRecvTcpPort);
                listener.Start();
                try
                {
                    this.m_bRecvTcp = true;
                    while (this.m_bRecvTcp)
                    {
                        Socket socket = listener.AcceptSocket();
                        try
                        {
                            try
                            {
                                if (!socket.Connected)
                                {
                                    continue;
                                }
                                NetworkStream stream = new NetworkStream(socket);
                                if (stream.CanRead)
                                {
                                    byte[] buffer = new byte[0x400];
                                    StringBuilder builder = new StringBuilder();
                                    int count = 0;
                                    do
                                    {
                                        count = stream.Read(buffer, 0, buffer.Length);
                                        builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, count));
                                    }
                                    while (stream.DataAvailable);
                                    string str = builder.ToString();
                                    if (str.Trim() == "")
                                    {
                                        continue;
                                    }
                                    switch (int.Parse(str.Substring(0, 2)))
                                    {
                                        case 1:
                                            this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "IP数据报", "接收", str });
                                            break;

                                        case 2:
                                            this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "回执IP数据报文", "接收", str });
                                            break;

                                        case 3:
                                            this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "传输异常报", "接收", str });
                                            break;

                                        case 4:
                                            this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "通信确认报", "接收", str });
                                            break;

                                        case 5:
                                            this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "主机IP地址更改通知报", "接收", str });
                                            break;
                                    }
                                }
                                stream.Close();
                            }
                            catch (Exception exception)
                            {
                                string message = exception.Message;
                            }
                            continue;
                        }
                        finally
                        {
                            socket.Close();
                        }
                    }
                }
                catch (Exception exception2)
                {
                    string text2 = exception2.Message;
                }
                finally
                {
                    listener.Stop();
                }
            }
            catch (Exception exception3)
            {
                string text3 = exception3.Message;
            }
        }

        private void threadListenUdp()
        {
            try
            {
                UdpClient client = new UdpClient(this.m_nRecvUdpPort);
                try
                {
                    this.m_bRecvUdp = true;
                    while (this.m_bRecvUdp)
                    {
                        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, this.m_nRecvUdpPort);
                        byte[] buffer = client.Receive(ref remoteEP);
                        if (((buffer.Length != 4) || (buffer[0] != 0)) || (((buffer[1] != 0) || (buffer[2] != 0)) || (buffer[3] != 0)))
                        {
                            int num = 0;
                            for (int i = 0; i < (buffer.Length - 1); i++)
                            {
                                if ((buffer[i] == 1) && (buffer[i + 1] == 1))
                                {
                                    num = i;
                                    break;
                                }
                                num = i;
                            }
                            string strSend = "";
                            if (num != (buffer.Length - 1))
                            {
                                byte[] bytes = new byte[buffer.Length - num];
                                for (int j = 0; j < bytes.Length; j++)
                                {
                                    bytes[j] = buffer[j + num];
                                }
                                strSend = Encoding.Default.GetString(bytes);
                            }
                            string strPacketSend = getALPacket(strSend);
                            this.TcpSend(this.m_SendTcpIp, this.m_nSendTcpPort, strPacketSend);
                            switch (int.Parse(strPacketSend.Substring(0, 2)))
                            {
                                case 1:
                                    {
                                        this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "IP数据报", "发送", strPacketSend });
                                        continue;
                                    }
                                case 2:
                                    {
                                        this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "回执IP数据报文", "发送", strPacketSend });
                                        continue;
                                    }
                                case 3:
                                    {
                                        this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "传输异常报", "发送", strPacketSend });
                                        continue;
                                    }
                                case 4:
                                    {
                                        this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "通信确认报", "发送", strPacketSend });
                                        continue;
                                    }
                                case 5:
                                    {
                                        this.listViewInfo.Invoke(new delegateInsertList(this.InsertList), new object[] { "主机IP地址更改通知报", "发送", strPacketSend });
                                        continue;
                                    }
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    string message = exception.Message;
                }
                finally
                {
                    client.Close();
                }
            }
            catch (Exception exception2)
            {
                string text2 = exception2.Message;
            }
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x511:
                    base.Visible = true;
                    base.Show();
                    base.TopMost = true;
                    break;

                case 0x512:
                    base.Visible = false;
                    break;

                case 0x513:
                    Application.Exit();
                    break;
            }
            base.WndProc(ref m);
        }

        public static string getALPacket(string strSend)
        {
            int startIndex = 0;
            string str = "";
            if (startIndex <= -1)
            {
                return str;
            }
            string str2 = strSend.Substring(startIndex, 0x18);
            startIndex += 0x18;
            int num2 = int.Parse(strSend.Substring(startIndex, 2));
            startIndex += 2;
            string str4 = "";
            for (int i = 0; i < num2; i++)
            {
                string str5 = strSend.Substring(startIndex, 9);
                str5 = str5.Substring(1, str5.Length - 1);
                str4 = str4 + str5;
                startIndex += 9;
            }
            string str6 = str4;
            string str7 = strSend.Substring(startIndex, strSend.Length - startIndex);
            int index = str7.IndexOf("\x0002");
            int num5 = str7.IndexOf('-');
            string str8 = "";
            if ((index > -1) && (num5 > -1))
            {
                str8 = str7.Substring(index + 1, (num5 - index) - 1);
            }
            int num6 = ((((13 + (8 * num2)) + 10) + str2.Length) + str6.Length) + str7.Length;
            string str9 = "";
            for (int j = 0; j < (10 - str8.Length); j++)
            {
                str9 = str9 + "0";
            }
            str9 = str9 + str8;
            return ("01" + num6.ToString("0000") + "00013" + num2.ToString("00") + str4 + str9 + str2 + str6 + str7);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.InitPort();
            Thread thread = new Thread(new ThreadStart(this.threadListenUdp));
            thread.IsBackground = true;
            thread.Start();
            Thread thread2 = new Thread(new ThreadStart(this.threadListenTcp));
            thread2.IsBackground = true;
            thread2.Start();
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            //base.Visible = false;
        }
    }
}
